<?php

namespace app\api\logic;
use think\facade\Db;
class UploadGoogleLogic extends BasicLogic
{
    
    /**
     * @desc    上传视频信息
     * @author  zhangheng
     * @date    2025-07-03
     */
    public function uploadVideo($file=[]){

        $google_ads_token = Db::name('google_ads_token')->where('id',1)->value('access_token');
        $iscustom['access_token'] = $google_ads_token;
        $iscustom['developer_token'] = Config('Logisticskey.google_info.api_token') ?? "";
        $iscustom['login_customer_id'] = Config('Logisticskey.google_info.ads_id');
        
        // 配置参数（需自行替换）
        $access_token = $google_ads_token; // 已获取的有效访问令牌
        $file_path = 'video.mp4';            // 本地MP4文件路径
        $folder_id = null;                   // 目标文件夹ID（可选）
        // 文件信息
        $file_name = basename($file_path);
        $mime_type = 'video/mp4';
        // $file_size = filesize($file_path);
        // $chunk_size = 256 * 1024 * 1024;    // 256MB分块大小

        // 1. 创建续传会话
        $session_url = $this->createResumableSession($access_token, $file_name, $mime_type, $folder_id);
        
        // 2. 分块上传文件
        // $this->uploadChunks($session_url, $file_path, $file_size, $chunk_size);
        
    }

    /**
     * 创建续传会话
     */
    public function createResumableSession($access_token, $file_name, $mime_type, $folder_id = null) {
        // $url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable';
        $url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media';
        $headers = [
            "Authorization: Bearer $access_token",
            'Content-Type: application/json; charset=UTF-8',
            'X-Upload-Content-Type: ' . $mime_type,
        ];
    
        $body = [
            'name' => $file_name
        ];
    
        if ($folder_id) {
            $body['parents'] = [$folder_id];
        }
    
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POSTFIELDS => json_encode($body),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => true,
            CURLOPT_FOLLOWLOCATION => false
        ]);
    
        $response = curl_exec($ch);
        halt($response);
        
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
        if ($http_code != 200) {
            throw new \Exception("创建续传会话失败: " . $this->getResponseBody($ch));
        }
    
        // 提取Location头中的会话URL
        preg_match('/Location: (.*)\r\n/', $response, $matches);
        $session_url = trim($matches[1]);
        
        if (!$session_url) {
            throw new \Exception("无法获取续传会话URL");
        }
    
        curl_close($ch);
        return $session_url;
    }
        
    /**
     * 分块上传文件
     */
    public function uploadChunks($session_url, $file_path, $file_size, $chunk_size) {
        $file_handle = fopen($file_path, 'rb');
        $bytes_uploaded = 0;
        $session_state = []; // 用于保存上传状态（实际使用时建议持久化存储）
    
        // 尝试从保存的状态恢复上传
        if (!empty($session_state)) {
            $bytes_uploaded = $session_state['uploaded'];
            fseek($file_handle, $bytes_uploaded);
        }
    
        while ($bytes_uploaded < $file_size) {
            // 计算当前块范围
            $start = $bytes_uploaded;
            $end = min($bytes_uploaded + $chunk_size - 1, $file_size - 1);
            $chunk_length = $end - $start + 1;
            $mime_type = 'video/mp4';
            // 设置请求头
            $headers = [
                "Authorization: Bearer " . getAccessToken(),
                'Content-Range: bytes ' . $start . '-' . $end . '/' . $file_size,
                'Content-Length: ' . $chunk_length,
                'Content-Type: ' . $mime_type
            ];
    
            // 执行上传
            $ch = curl_init($session_url);
            curl_setopt_array($ch, [
                CURLOPT_CUSTOMREQUEST => 'PUT',
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_INFILE => $file_handle,
                CURLOPT_INFILESIZE => $chunk_length,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HEADER => true
            ]);
    
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
            // 处理响应
            if ($http_code == 308) { // 308 Resume Incomplete 表示需要继续上传
                // 更新上传状态
                $bytes_uploaded += $chunk_length;
                $session_state = [
                    'uploaded' => $bytes_uploaded,
                    'session_url' => $session_url
                ];
                
                // 可选：持久化保存session_state用于断点续传
                // file_put_contents('upload_state.json', json_encode($session_state));
                
                echo "已上传: " . round($bytes_uploaded / $file_size * 100, 2) . "%\n";
            } elseif ($http_code == 200) { // 上传完成
                echo "文件上传完成！\n";
                break;
            } else {
                throw new \Exception("上传失败: " . $this->getResponseBody($ch));
            }
    
            curl_close($ch);
        }
    
        fclose($file_handle);
    }
        
    /**
     * 获取响应体（处理HTTP响应）
     */
    public function getResponseBody($ch) {
        $response = curl_exec($ch);
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        return substr($response, $header_size);
    }

}